package com.ruoyi.charge.service.impl;

import com.ruoyi.charge.domain.ChargingBill;
import com.ruoyi.charge.rabbitmq.DelayExchangeConfig;
import com.ruoyi.charge.service.IChargingBillService;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;

@Service
public class ChargingBillServiceImpl implements IChargingBillService {
    @Autowired
    RabbitTemplate rabbitTemplate;

    //ConfirmCallback是一个回调接口，用于处理消息发送到交换机后的确认结果
    RabbitTemplate.ConfirmCallback confirmCallback =
            new RabbitTemplate.ConfirmCallback() {
                @Override
                public void confirm(CorrelationData correlationData,
                                    boolean ack,
                                    String cause) {
                    System.out.println("消息到达交换机");
                }
            };

    //ReturnsCallback是一个回调接口，用于处理发送到交换机但未被路由到任何队列的消息返回结果。
    //在RabbitMQ中，当消息被发送到交换机，但无法路由到任何队列时，
    //可以设置消息返回（returns）机制来处理这种情况。
    RabbitTemplate.ReturnsCallback returnsCallback =
            new RabbitTemplate.ReturnsCallback() {
                @Override
                public void returnedMessage(ReturnedMessage returned) {
                    System.out.println("到达队列");
                }
            };

    //MessagePostProcessor接口只有一个方法，
    //即postProcessMessage(Message message)方法。
    //该方法接收一个Message对象作为参数，返回经过后处理的Message对象。
    //在该方法内部，可以对消息的属性、头部或消息体进行任何必要的修改。
    //org.springframework.amqp.core;
    MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
        @Override
        public Message postProcessMessage(Message message) throws AmqpException {
            MessageProperties messageProperties = message.getMessageProperties();
            messageProperties.setHeader("x-delay", 10 * 1000);//消息延迟10秒处理
            return message;
        }
    };

    @Override
    public boolean createBill(ChargingBill chargingBill) {
        SimpleDateFormat simpleDateFormat =
                new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        System.out.println("发送时间" + simpleDateFormat.format(new Date()));

        //public void setConfirmCallback(RabbitTemplate.ConfirmCallback confirmCallback)
        //public interface ConfirmCallback
        //把实现类的对象传给框架
        //设置消息发送确认回调
        rabbitTemplate.setConfirmCallback(confirmCallback);

        //public void setReturnsCallback(RabbitTemplate.ReturnsCallback returnCallback)
        //public interface ReturnsCallback
        //设置消息返回回调
        rabbitTemplate.setReturnsCallback(returnsCallback);

        //public void convertAndSend(String exchange, String routingKey, final Object message,
        //			final MessagePostProcessor messagePostProcessor)
        //public interface MessagePostProcessor
        //发送延迟消息到指定的交换机和路由键
        rabbitTemplate.convertAndSend(DelayExchangeConfig.DELAY_EXCHANGE,
                "delay.60000", chargingBill, messagePostProcessor);
        return true;
    }
}
